using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using cb0tServer;

namespace sb0t_winGUI
{
    public partial class Form1 : Form
    {
        private bool drag = false;
        private Point pos = new Point();
        private bool server_running = false;
        private ServerCore server;

        private Form2 commands_gui;
        private Quiz quiz_form;

        public Form1()
        {
            InitializeComponent();
            
            RunOnceFileUpdater.DoJobs();
            this.commands_gui = new Form2();
            WebServerSettings.Load();

            AdminLog.Init();
            StringTemplate.Init();
            MOTD.Init();
            Passwords.Load();
            String[] passwords = Passwords.GetPasswords();

            if (passwords != null)
                foreach (String str in passwords)
                    this.listBox1.Items.Add(str);

            CoreSettings.Load();

            this.quiz_form = new Quiz();
            this.textBox3.Text = CoreSettings.room_name;
            this.textBox4.Text = CoreSettings.room_port.ToString();
            this.textBox1.Text = CoreSettings.pm_reply;

            if (this.textBox1.Text.Length > 2)
                this.textBox1.Text = this.textBox1.Text.Replace("\r\n", "");

            this.textBox5.Text = CoreSettings.additional_host.ToString();
            this.textBox9.Text = CoreSettings.additional_host_pass;
            this.textBox6.Text = WebServerSettings.port.ToString();
            this.textBox7.Text = CoreSettings.room_bot;
            this.checkBox4.Checked = CoreSettings.supports_custom_emoticons;
            this.checkBox3.Checked = CoreSettings.allow_linking;
            this.checkBox5.Checked = CoreSettings.allow_linked_admins;
            this.checkBox5.Enabled = this.checkBox3.Checked;
            this.checkBox7.Checked = CoreSettings.allow_audio;
            this.checkBox8.Checked = CoreSettings.allow_video;
            this.checkBox9.Checked = CoreSettings.allow_images;
            this.checkBox10.Checked = CoreSettings.allow_documents;
            this.checkBox11.Checked = CoreSettings.allow_software;
            this.checkBox12.Checked = CoreSettings.allow_other;
            this.checkBox13.Checked = CoreSettings.avatars;
            this.checkBox14.Checked = CoreSettings.min_age_enabled;
            this.numericUpDown2.Value = (decimal)CoreSettings.min_age_value;

            if (CoreSettings.UDPAddress.Equals(System.Net.IPAddress.Any))
                this.textBox10.Text = "";
            else
                this.textBox10.Text = CoreSettings.UDPAddress.ToString();

            if (CoreSettings.link_any)
            {
                this.radioButton1.Checked = true;
                this.radioButton2.Checked = false;
            }
            else
            {
                this.radioButton2.Checked = true;
                this.radioButton1.Checked = false;
            }

            this.radioButton1.Enabled = this.checkBox3.Checked;
            this.radioButton2.Enabled = this.checkBox3.Checked;
            this.checkBox6.Checked = CoreSettings.chat_logging;

            this.comboBox1.SelectedIndex = CoreSettings.room_language;
            this.numericUpDown3.Value = CoreSettings.dint;
            this.checkBox15.Checked = CoreSettings.show_on_list;
            this.numericUpDown4.Value = CoreSettings.clear_ban_interval;
            this.checkBox16.Checked = CoreSettings.clear_ban_enabled;
            this.checkBox17.Checked = CoreSettings.gender_allow_male;
            this.checkBox18.Checked = CoreSettings.gender_allow_female;
            this.checkBox19.Checked = CoreSettings.gender_allow_unknown;
            this.checkBox20.Checked = CoreSettings.can_vc;
            this.checkBox21.Checked = CoreSettings.can_dc;
            this.checkBox22.Checked = CoreSettings.captcha;

            CoreSettings.let_save = true;

            Avatar.Load();
            Avatar.LoadDefault();

            if (Avatar.sb0t_avatar_image != null)
                this.pictureBox1.Image = Avatar.sb0t_avatar_image;
            else
                this.pictureBox1.Image = Avatar.blank;

            if (Avatar.default_av != null)
                this.pictureBox2.Image = Avatar.default_av;
            else
                this.pictureBox2.Image = Avatar.blank;

            LinkAllowList.Load();

            String[] allowed_rooms = LinkAllowList.GetList();

            if (allowed_rooms != null)
                foreach (String str in allowed_rooms)
                    this.listBox2.Items.Add(str);

            RoomSearch.InitializeBackgroundWorker();
            AutoStart.Load();

            if (AutoStart.RunOnPowerUp) checkBox1.Checked = true;

            if (AutoStart.StartOnLoad)
            {
                checkBox2.Checked = true;
                button1_Click("autostart", new EventArgs());
            }
        }

        #region form_appearance
        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaintBackground(e);

            Graphics g = e.Graphics;
            Rectangle r = new Rectangle(0, 0, this.Width, this.Height);

            for (int i = 2; i < 10; i++)
            {
                g.DrawRectangle(new Pen(Color.FromArgb((i * 25), (i * 25), (i * 25)), 1), r);
                r = new Rectangle(i - 2, i - 2, this.Width - (2 * (i - 2)), this.Height - (2 * (i - 2)));
            }

            LinearGradientBrush l = new LinearGradientBrush(r,
                Color.FromArgb(210, 210, 210),
                Color.FromArgb(255, 255, 255),
                45f);

            g.FillRectangle(l, r);

            g.DrawLine(new Pen(Brushes.DarkGray, 2), new Point(6, 32), new Point(this.Width - 5, 32));

            r = new Rectangle(6, 7, this.Width - 12, 24);
            g.FillRectangle(Brushes.LightGray, r);

            Font f = new System.Drawing.Font("Verdana", 10F, System.Drawing.FontStyle.Regular,
                System.Drawing.GraphicsUnit.Point, ((byte)(0)));

            g.DrawString("sb0t by oobe", f, Brushes.Black, new PointF(10, 10));

            l.Dispose();

            this.Opacity = 0.90;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this.drag)
            {
                Point p1 = new Point(e.X, e.Y);
                Point p2 = this.PointToScreen(p1);
                Point p3 = new Point(p2.X - this.pos.X,
                                     p2.Y - this.pos.Y);
                this.Location = p3;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            this.drag = false;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (e.X >= 6 && e.X <= 318)
            {
                if (e.Y >= 6 && e.Y <= 32)
                {
                    this.drag = true;
                    this.pos = new Point(e.X, e.Y);
                }
            }
        }
        #endregion

        private void hideButton1_Click(object sender, EventArgs e)
        {
            this.notifyIcon1.Visible = true;
            this.Hide();
        }

        private void closeButton1_Click(object sender, EventArgs e)
        {
            DialogResult r = MessageBox.Show("Are you sure you want to close sb0t?",
                "sb0t", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (r == DialogResult.Yes)
                this.Close();
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            this.notifyIcon1.Visible = false;
            this.Show();
        }

        private void button1_Click(object sender, EventArgs e) // start-stop server
        {
            if (!this.server_running) // start the server
            {
                CoreSettings.room_name = this.textBox3.Text;

                if (CoreSettings.room_name.Length < 2)
                {
                    MessageBox.Show("Room name must be at least 2 characters long",
                        "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                CoreSettings.room_bot = this.textBox7.Text;

                int _eval_bot_name = Encoding.UTF8.GetByteCount(CoreSettings.room_bot);

                if (_eval_bot_name < 2 || _eval_bot_name > 20)
                {
                    MessageBox.Show("Bot name must be between 2 and 20 bytes long",
                        "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!ushort.TryParse(this.textBox4.Text, out CoreSettings.room_port))
                {
                    MessageBox.Show("Please select a valid server port",
                        "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!ushort.TryParse(this.textBox6.Text, out WebServerSettings.port))
                {
                    MessageBox.Show("Please select a valid http port",
                        "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!System.Net.IPAddress.TryParse(this.textBox5.Text, out CoreSettings.additional_host))
                {
                    MessageBox.Show("Please select a valid Additional Host IP Address",
                        "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!System.Net.IPAddress.TryParse(this.textBox10.Text, out CoreSettings.UDPAddress))
                {
                    CoreSettings.UDPAddress = System.Net.IPAddress.Any;
                    this.textBox10.Clear();
                }

                CoreSettings.additional_host_pass = this.textBox9.Text.Trim();
                CoreSettings.pm_reply = this.textBox1.Text;
                CoreSettings.allow_audio = this.checkBox7.Checked;
                CoreSettings.allow_video = this.checkBox8.Checked;
                CoreSettings.allow_images = this.checkBox9.Checked;
                CoreSettings.allow_documents = this.checkBox10.Checked;
                CoreSettings.allow_software = this.checkBox11.Checked;
                CoreSettings.allow_other = this.checkBox12.Checked;

                try
                {
                    CoreSettings.Save();
                }
                catch { }

                try
                {
                    CoreSettings.SaveNew();
                }
                catch { }

                try
                {
                    WebServerSettings.Save();
                }
                catch { }

                this.server_running = true;
                this.button1.Text = "Stop Server";
                this.textBox3.Focus();
                this.textBox1.Enabled = false;
                this.textBox3.Enabled = false;
                this.textBox4.Enabled = false;
                this.textBox5.Enabled = false;
                this.textBox6.Enabled = false;
                this.textBox7.Enabled = false;
                this.textBox9.Enabled = false;

                this.checkBox4.Enabled = false;
                this.checkBox7.Enabled = false;
                this.checkBox8.Enabled = false;
                this.checkBox9.Enabled = false;
                this.checkBox10.Enabled = false;
                this.checkBox11.Enabled = false;
                this.checkBox12.Enabled = false;
                this.checkBox13.Enabled = false;
                this.textBox10.Enabled = false;
                this.checkBox15.Enabled = false;
                this.checkBox20.Enabled = false;
                this.checkBox21.Enabled = false;
                this.checkBox22.Enabled = false;

                this.server = new ServerCore();
                this.server.Init();
            }
            else // stop the server
            {
                this.server_running = false;
                this.button1.Text = "Start Server";
                this.textBox1.Enabled = true;
                this.textBox3.Enabled = true;
                this.textBox4.Enabled = true;
                this.textBox5.Enabled = true;
                this.textBox6.Enabled = true;
                this.textBox7.Enabled = true;
                this.textBox9.Enabled = true;

                this.checkBox4.Enabled = true;
                this.checkBox7.Enabled = true;
                this.checkBox8.Enabled = true;
                this.checkBox9.Enabled = true;
                this.checkBox10.Enabled = true;
                this.checkBox11.Enabled = true;
                this.checkBox12.Enabled = true;
                this.checkBox13.Enabled = true;
                this.textBox10.Enabled = true;
                this.checkBox15.Enabled = true;
                this.checkBox20.Enabled = true;
                this.checkBox21.Enabled = true;
                this.checkBox22.Enabled = true;

                this.textBox3.Focus();
                this.server.Kill();
            }
        }

        private void button2_Click(object sender, EventArgs e) // add password
        {
            this.textBox2.Focus();

            String str = this.textBox2.Text;

            if (str.Length < 2)
            {
                MessageBox.Show("Passwords must be 2 or more characters long",
                    "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!Passwords.AddPassword(str, (int)numericUpDown1.Value)) // password already exists
            {
                MessageBox.Show("This password already exists",
                    "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            this.textBox2.Clear();
            this.listBox1.Items.Add(str);
        }

        private void removeToolStripMenuItem_Click(object sender, EventArgs e) // remove password
        {
            String str = (String)this.listBox1.SelectedItem;

            if (Passwords.RemovePassword(str))
                this.listBox1.Items.Remove(str);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            RoomSearch.terminate = true;

            if (this.server_running)
                if (this.server != null)
                    this.server.Kill();
        }

        private void button4_Click(object sender, EventArgs e) // edit motd
        {
            this.textBox3.Focus();
            System.Diagnostics.Process.Start(sb0t_winGUI.RunOnceFileUpdater.sbotpath);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e) // auto load sb0t
        {
            AutoStart.SetAutoRunOnPowerUp(checkBox1.Checked);
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e) // auto start server
        {
            AutoStart.SetAutoStartOnLoad(checkBox2.Checked);
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e) // website enabled
        {
            CoreSettings.supports_custom_emoticons = this.checkBox4.Checked;
            CoreSettings.SaveNew();
        }

        private void button6_Click(object sender, EventArgs e) // command levels
        {
            this.commands_gui.Show();
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e) // link enable ??
        {
            this.checkBox5.Enabled = this.checkBox3.Checked;
            this.radioButton1.Enabled = this.checkBox3.Checked;
            this.radioButton2.Enabled = this.checkBox3.Checked;
            CoreSettings.allow_linking = this.checkBox3.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e) // linked admins ??
        {
            CoreSettings.allow_linked_admins = this.checkBox5.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox5_MouseUp(object sender, MouseEventArgs e)
        {
            if (this.checkBox5.Checked)
            {
                DialogResult dr = MessageBox.Show("WARNING: Enabling this option will allow linked level 4 and 5 admins to kill, ban, muzzle, and unmuzzle users in your chatroom.  Continue?",
                    "sb0t", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

                if (dr == DialogResult.No)
                    this.checkBox5.Checked = false;
            }
        }

        private void checkBox6_CheckedChanged(object sender, EventArgs e) // chat logging ??
        {
            CoreSettings.chat_logging = this.checkBox6.Checked;
            CoreSettings.SaveNew();
        }

        private void button7_Click(object sender, EventArgs e) // add room to link allow list
        {
            Ares.CommonObjects.ChannelListItem _decrypted = Ares.Protocols.Hashlinks.DecodeHashlink(this.textBox8.Text);

            if (_decrypted == null)
            {
                MessageBox.Show("Invalid hashlink!",
                    "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (_decrypted.name.Length == 0)
            {
                MessageBox.Show("Invalid hashlink!",
                    "sb0t", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (LinkAllowList.AddItem(_decrypted))
                this.listBox2.Items.Add(_decrypted.name);

            this.textBox8.Clear();
            this.textBox8.Focus();
        }

        private void radioButton2_MouseUp(object sender, MouseEventArgs e) // link list only
        {
            if (this.radioButton2.Enabled)
            {
                this.radioButton1.Checked = false;
                CoreSettings.link_any = false;
                CoreSettings.SaveLinkAny();
            }
        }

        private void radioButton1_MouseUp(object sender, MouseEventArgs e) // link any
        {
            if (this.radioButton1.Enabled)
            {
                this.radioButton2.Checked = false;
                CoreSettings.link_any = true;
                CoreSettings.SaveLinkAny();
            }
        }

        private void removeToolStripMenuItem1_Click(object sender, EventArgs e) // remove allow link room
        {
            String str = (String)this.listBox2.SelectedItem;

            if (LinkAllowList.RemoveItem(str))
                this.listBox2.Items.Remove(str);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) // server language change
        {
            CoreSettings.room_language = (byte)this.comboBox1.SelectedIndex;
            CoreSettings.SaveNew();
        }

        private void button8_Click(object sender, EventArgs e) // join my room
        {
            if (this.server_running)
            {
                String hash = Ares.Protocols.Hashlinks.EncodeHashlink(new Ares.CommonObjects.ChannelListItem(CoreSettings.room_name, Topics.GetMainTopic(),
                    CoreSettings.room_port, 0, System.Net.IPAddress.Loopback, System.Net.IPAddress.Loopback));

                if (hash != null)
                {
                    hash = "arlnk://" + hash;

                    try
                    {
                        System.Diagnostics.Process.Start(hash);
                    }
                    catch { }
                }
            }
        }

        private void checkBox13_CheckedChanged(object sender, EventArgs e) // enable avatars
        {
            CoreSettings.avatars = this.checkBox13.Checked;
            CoreSettings.SaveNew();
        }

        private void button9_Click(object sender, EventArgs e) // change avatar
        {
            OpenFileDialog f = new OpenFileDialog();
            f.Multiselect = false;
            f.Filter = "Supported file types (*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|Bitmap files (*.bmp)|*.bmp|Jpeg files (*.jpg)|*.jpg|PNG files (*.png)|*.png";

            if (f.ShowDialog() == DialogResult.OK)
            {
                Avatar.Update(f.FileName);

                if (Avatar.sb0t_avatar_image != null)
                    this.pictureBox1.Image = Avatar.sb0t_avatar_image;
                else
                    this.pictureBox1.Image = Avatar.blank;
            }
        }

        private void numericUpDown2_Leave(object sender, EventArgs e) // minimum age changed
        {
            CoreSettings.min_age_value = (byte)this.numericUpDown2.Value;
            CoreSettings.SaveNew();
        }

        private void checkBox14_CheckedChanged(object sender, EventArgs e) // enable minimum age monitoring
        {
            CoreSettings.min_age_enabled = this.checkBox14.Checked;
            CoreSettings.SaveNew();
        }

        private void numericUpDown3_ValueChanged(object sender, EventArgs e)
        {
            CoreSettings.dint = (int)this.numericUpDown3.Value;
        }

        private void numericUpDown3_Leave(object sender, EventArgs e)
        {
            CoreSettings.SaveNew();
        }

        private void checkBox15_CheckedChanged(object sender, EventArgs e) // enable listing
        {
            CoreSettings.show_on_list = this.checkBox15.Checked;
            CoreSettings.SaveNew();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog f = new OpenFileDialog();
            f.Multiselect = false;
            f.Filter = "Supported file types (*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|Bitmap files (*.bmp)|*.bmp|Jpeg files (*.jpg)|*.jpg|PNG files (*.png)|*.png";

            if (f.ShowDialog() == DialogResult.OK)
            {
                Avatar.UpdateDefault(f.FileName);

                if (Avatar.sb0t_avatar_image != null)
                    this.pictureBox2.Image = Avatar.default_av;
                else
                    this.pictureBox2.Image = Avatar.blank;
            }
        }

        private void button5_Click(object sender, EventArgs e) // quiz
        {
            this.quiz_form.Show();
        }

        private void numericUpDown4_Leave(object sender, EventArgs e)
        {
            CoreSettings.clear_ban_interval = (int)this.numericUpDown4.Value;
            CoreSettings.SaveNew();
        }

        private void checkBox16_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.clear_ban_enabled = this.checkBox16.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox17_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.gender_allow_male = this.checkBox17.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox18_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.gender_allow_female = this.checkBox18.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox19_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.gender_allow_unknown = this.checkBox19.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox20_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.can_vc = this.checkBox20.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox21_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.can_dc = this.checkBox21.Checked;
            CoreSettings.SaveNew();
        }

        private void checkBox7_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void checkBox22_CheckedChanged(object sender, EventArgs e)
        {
            CoreSettings.captcha = this.checkBox22.Checked;
            CoreSettings.SaveNew();
        }

    }
}